博客
关于我
使用NanoHttpd在Android项目中搭建服务器
阅读量:801 次
发布时间:2019-03-25

本文共 5982 字,大约阅读时间需要 19 分钟。

小型HTTP服务器NanoHTTPD的配置与使用

作为一名开发人员,如果你需要快速搭建一个轻量级的HTTP服务器,NanoHTTPD是一个非常不错的选择。它不仅支持常见的HTTP方法(如GET、POST、PUT、HEAD和DELETE),还能方便地嵌入到Java程序中,同时占用内存非常小。这意味着它非常适合开发需要一个简单服务器来处理文件上传或API请求的项目。

为什么选择NanoHTTPD?

NanoHTTPD的优势在于:

  • 超轻量:仅需要一个Java文件即可运行,无需外部依赖。
  • 功能全面:支持多种HTTP方法和文件上传。
  • 易于嵌入:可以直接在Java程序中使用,完全按照你的需求定制。

接下来,我将指导你如何在项目中集成NanoHTTPD,并通过代码示例展示如何使用它来快速搭建一个文件服务器。


快速上手指南

1. 添加依赖

如果你不想直接从GitHub下载,可以在项目的build.gradle文件中添加依赖。我假设你项目结构如下:

your-project/├── build.gradle└── src/    └── main/        └── java/            └── YourPackage/                └── YourServer.java

build.gradle中添加以下依赖:

dependencies {    implementation 'org.nanohttpd:nanohttpd:2.2.0'}

2. 创建文件服务器

假设你想在项目中创建一个简单的文件服务器。那我们就从YourPackage包下创建一个继承自NanoHTTPDFileServer类。

package caro.automation.server;import org.nanohttpd.protocols.http.IHTTPSession;import org.nanohttpd.protocols.http.NanoHTTPD;import org.nanohttpd.protocols.http.response.Response;import org.nanohttpd.protocols.http.response.Status;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.util.List;public class FileServer extends NanoHTTPD {    private static final int DEFAULT_PORT = 8080;    private static final String TAG = "FileServer";    private List
fileList; // constructor public FileServer(List
fileList) { super(DEFAULT_PORT); this.fileList = fileList; } // 掏个小窍门:_MAGIC_TAG_ 这里是你的独特标签 private static final String REQUEST_ROOT = "/"; @Override public Response serve(IHTTPSession session) { String uri = session.getUri(); if (uri.equals(REQUEST_ROOT) || uri.isEmpty()) { return responseRootPage(session); } else { return responseFile(session); } } private Response responseRootPage(IHTTPSession session) { StringBuilder builder = new StringBuilder(); builder.append(""); // 开始生成HTML builder.append("
File List"); builder.append(""); for (File file : fileList) { if (file.exists()) { builder.append("
"); builder.append("
"); builder.append(file.getName()); builder.append(""); builder.append("
"); } } builder.append(""); return Response.newFixedLengthResponse(builder.toString()); } private Response responseFile(IHTTPSession session) { try { String uri = session.getUri(); FileInputStream fis = new FileInputStream(uri); // 返回OK响应,指定文件类型 return Response.newFixedLengthResponse(Status.OK, "application/octet-stream", fis, fis.available()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // 遇到未找到的文件,返回404 return response404(session, uri); } private Response response404(IHTTPSession session, String url) { StringBuilder builder = new StringBuilder(); builder.append("
404 - File Not Found"); builder.append("

Sorry, Can't Found

"); builder.append("

\"" + url + "\" Undefined!

"); builder.append(""); return Response.newFixedLengthResponse(builder.toString()); }}

3. 启动服务器

创建一个服务类来启动FileServer,例如:

package caro.automation.server;import org.nanohttpd.protocols.http.IHTTPSession;import org.nanohttpd.protocols.http.NanoHTTPD;import org.nanohttpd.protocols.http.response.Response;import org.nanohttpd.protocols.http.response.Status;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.util.List;import caro.automation.MyApplication;import caro.automation.DatabaseSelectUpload;public class HttpServer extends NanoHTTPD {    private static final String TAG = "HttpServer";    private static final int DEFAULT_PORT = 8080;    public HttpServer(int port) {        super(port);    }    @Override    public Response serve(IHTTPSession session) {        try {            // 根据自己的项目逻辑获取文件列表            // 这里暂时假设fileList是动态加载的,或者从数据库中获取            for (String file : DatabaseSelectUpload.name_) {                session.parseBody(new HashMap<>());                String filePath = MyApplication.GetApp().getExternalFilesDir(null) + "/你的文件路径";                // 获取完整的文件路径                File targetFile = new File(filePath + "/" + file + ".db3");                if (targetFile.exists()) {                    FileInputStream fis = new FileInputStream(targetFile);                    return Response.newFixedLengthResponse(Status.OK, "application/octet-stream",                            fis, fis.available());                }            }        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return response404(session, "/你的URL");    }    @Override    public Response response404(IHTTPSession session, String url) {        StringBuilder builder = new StringBuilder();        builder.append("404 - NotFound");        builder.append("

404 - File Not Found

"); builder.append("

\"" + url + "\" - File does not exist.

"); builder.append(""); return Response.newFixedLengthResponse(builder.toString()); } public static void main(String[] args) { // 在这里启动你需要的服务 // 比如:你可能需要修改为startService,而不仅仅是启动服务器 }}

4. 启动与关闭服务器

在需要的时候启动服务器,你可以在onCreate方法中启动,onDestroy方法中停止:

public class MyServer extends HttpServer {    public MyServer() {        super(DEFAULT_PORT);    }    @Override    public void onDestroy() {        super.stopService(new Intent(getApplicationContext(), MyServer.class));    }}

注意事项

  • 文件路径管理:确保文件路径是正确的,尤其是在不同操作系统上测试时。
  • 权限设置:服务器需要有权限访问所需文件,否则会抛出FileInfoException或类似的错误。
  • 缓存机制:如果你需要缓存 frequent请求,可以自定义缓存策略。
  • 安全性:根据需要添加用户认证或权限检查,防止未授权访问。

  • 通过以上配置,你可以轻松实现一个嵌入式的HTTP服务器,支持文件上传和下载。你可以根据实际需求定制FileServer类或扩展其功能,使其更符合项目需求。

    转载地址:http://yqyyk.baihongyu.com/

    你可能感兴趣的文章
    MySql 手动执行主从备份
    查看>>
    Mysql 批量修改四种方式效率对比(一)
    查看>>
    mysql 批量插入
    查看>>
    Mysql 报错 Field 'id' doesn't have a default value
    查看>>
    MySQL 报错:Duplicate entry 'xxx' for key 'UNIQ_XXXX'
    查看>>
    Mysql 拼接多个字段作为查询条件查询方法
    查看>>
    mysql 排序id_mysql如何按特定id排序
    查看>>
    Mysql 提示:Communication link failure
    查看>>
    mysql 插入是否成功_PDO mysql:如何知道插入是否成功
    查看>>
    Mysql 数据库InnoDB存储引擎中主要组件的刷新清理条件:脏页、RedoLog重做日志、Insert Buffer或ChangeBuffer、Undo Log
    查看>>
    mysql 数据库中 count(*),count(1),count(列名)区别和效率问题
    查看>>
    mysql 数据库备份及ibdata1的瘦身
    查看>>
    MySQL 数据库备份种类以及常用备份工具汇总
    查看>>
    mysql 数据库存储引擎怎么选择?快来看看性能测试吧
    查看>>
    MySQL 数据库操作指南:学习如何使用 Python 进行增删改查操作
    查看>>
    MySQL 数据库的高可用性分析
    查看>>
    MySQL 数据库设计总结
    查看>>
    Mysql 数据库重置ID排序
    查看>>
    Mysql 数据类型一日期
    查看>>
    MySQL 数据类型和属性
    查看>>